#include "data_reporter.h"


std::vector<uint8_t> OpRangeData::encode()
{
    std::vector<uint8_t> result;
    encodeFixedData<int64_t>({start_ns, end_ns, sequence_number}, result);
    encodeFixedData<uint64_t>({process_id, start_thread_id, end_thread_id, forward_thread_id}, result);
    encodeFixedData<uint8_t>({scope}, result);
    result.push_back(is_async);
    encodeStrData(static_cast<uint16_t>(OpRangeDataType::NAME), name, result);
    if (!input_dtypes.empty()) {
        encodeStrArrayData(static_cast<uint16_t>(OpRangeDataType::INPUT_DTYPES), input_dtypes, result);
    }
    if (!input_shapes.empty()) {
        encode2DIntegerMatrixDatas<int64_t>(static_cast<uint16_t>(OpRangeDataType::INPUT_SHAPES), input_shapes, result);
    }
    if (!input_scalars.empty()) {
        encodeStrArrayData(static_cast<uint16_t>(OpRangeDataType::INPUT_SCALARS), input_scalars, result);
    }
    if (!stack.empty()) {
        encodeStrArrayData(static_cast<uint16_t>(OpRangeDataType::STACK), stack, result);
    }
    if (!module_hierarchy.empty()) {
        encodeStrArrayData(static_cast<uint16_t>(OpRangeDataType::MODULE_HIERARCHY), module_hierarchy, result);
    }

    std::vector<uint8_t> resultTLV;
    uint16_t dataType = static_cast<uint16_t>(OpRangeDataType::OP_RANGE_DATA);
    for (size_t i = 0; i < sizeof(uint16_t); ++i) {
        resultTLV.push_back((dataType >> (i * 8)) & 0xff);
    }
    uint32_t length = result.size();
    for (size_t i = 0; i < sizeof(uint32_t); ++i) {
        resultTLV.push_back((length >> (i * 8)) & 0xff);
    }
    resultTLV.insert(resultTLV.end(), result.cbegin(), result.cend());
    return resultTLV;
}
